#ifndef __DATA_STRUCTURES__
#define __DATA_STRUCTURES__

// includes

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <assert.h>

/**
 * A Queue node
 */
typedef struct DCQueueNode {

    void *data;
    struct DCQueueNode *next;

} DCQueueNode;

/**
 * This queue represents the pending list of
 * background requests (to switches) that must
 * be processed.
 */
typedef struct DCQueue {

    /**
     * number of nodes in the queue
     */

    int count;

    /**
     * Indicates the type of Queue
     */
    int isBlocking;

    /**
     * Condition variable for consumer
     */
    pthread_cond_t hasElementsCV;

    /**
     * mutex used controlling access
     * to the PendingRequests queue
     */
    pthread_mutex_t pendingQueueMutex;

    DCQueueNode *head;
    DCQueueNode *tail;

} DCQueue;

/**
 * initializes a PendingQueue
 */
void DCQueue_init(DCQueue *q, int isBlocking);

/**
 * destroys a pending queue
 */
void DCQueue_destroy(DCQueue *q);


/**
 * dequeues just the data and deallocates the
 * underlying node
 */
void* DCQueue_dequeueData(DCQueue *q);



/**
 * will block the caller until data exists in the underlying queue to be dequeued.
 */
void* DCQueue_waitAndDequeueData(DCQueue *q);

/**
 *
 * enqueues data into the caller specified queue
 *
 */
void DCQueue_enqueueData(DCQueue *q, void *data);

#endif


